package com.macro.mall.config;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.boot.actuate.info.InfoEndpoint;
import org.springframework.boot.actuate.metrics.MetricsEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 监控配置类
 * 用于配置应用监控、指标收集和日志记录
 * 
 * @author mall
 * @since 1.0
 */
@Configuration
public class MonitoringConfig {

    private static final Logger logger = LoggerFactory.getLogger(MonitoringConfig.class);

    /**
     * 自定义信息贡献者，为/actuator/info端点提供应用信息
     */
    @Bean
    public InfoContributor customInfoContributor() {
        return builder -> {
            Map<String, Object> appInfo = new HashMap<>();
            appInfo.put("name", "mall-admin");
            appInfo.put("description", "Mall管理后台应用");
            appInfo.put("version", "1.0-SNAPSHOT");
            appInfo.put("build-time", LocalDateTime.now().toString());
            appInfo.put("java-version", System.getProperty("java.version"));
            appInfo.put("spring-boot-version", "2.7.5");
            
            Map<String, Object> environment = new HashMap<>();
            environment.put("active-profiles", System.getProperty("spring.profiles.active", "default"));
            environment.put("server-port", System.getProperty("server.port", "8080"));
            environment.put("timezone", System.getProperty("user.timezone"));
            
            Map<String, Object> runtime = new HashMap<>();
            Runtime rt = Runtime.getRuntime();
            runtime.put("processors", rt.availableProcessors());
            runtime.put("memory-max", rt.maxMemory());
            runtime.put("memory-total", rt.totalMemory());
            runtime.put("memory-free", rt.freeMemory());
            runtime.put("memory-used", rt.totalMemory() - rt.freeMemory());
            
            builder.withDetail("app", appInfo);
            builder.withDetail("environment", environment);
            builder.withDetail("runtime", runtime);
        };
    }

    /**
     * 请求监控过滤器
     * 记录HTTP请求的响应时间和状态
     */
    @Bean
    public OncePerRequestFilter requestMonitoringFilter(MeterRegistry meterRegistry) {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request, 
                                          HttpServletResponse response, 
                                          FilterChain filterChain) throws ServletException, IOException {
                
                String uri = request.getRequestURI();
                String method = request.getMethod();
                long startTime = System.currentTimeMillis();
                
                try {
                    filterChain.doFilter(request, response);
                } finally {
                    long duration = System.currentTimeMillis() - startTime;
                    int status = response.getStatus();
                    
                    // 记录请求指标
                    Timer.Sample sample = Timer.start(meterRegistry);
                    sample.stop(Timer.builder("http.server.requests")
                        .tag("method", method)
                        .tag("uri", uri)
                        .tag("status", String.valueOf(status))
                        .register(meterRegistry));
                    
                    // 记录慢请求日志
                    if (duration > 1000) { // 超过1秒的请求
                        logger.warn("慢请求检测: " + method + " " + uri + " 耗时: " + duration + "ms, 状态: " + status);
                    }
                    
                    // 记录错误请求日志
                    if (status >= 400) {
                        logger.error("错误请求: " + method + " " + uri + " 状态: " + status + ", 耗时: " + duration + "ms");
                    }
                }
            }
            
            @Override
            protected boolean shouldNotFilter(HttpServletRequest request) {
                String uri = request.getRequestURI();
                // 跳过actuator端点的监控，避免循环
                return uri.startsWith("/actuator/");
            }
        };
    }

    /**
     * 应用启动监控
     */
    @Bean
    public ApplicationStartupMonitor applicationStartupMonitor() {
        return new ApplicationStartupMonitor();
    }

    /**
     * 应用启动监控类
     */
    public static class ApplicationStartupMonitor {
        private static final Logger startupLogger = LoggerFactory.getLogger("STARTUP");
        private final long startTime;
        
        public ApplicationStartupMonitor() {
            this.startTime = System.currentTimeMillis();
            startupLogger.info("=== Mall-Admin 应用启动开始 ===");
            startupLogger.info("启动时间: {}", LocalDateTime.now());
            startupLogger.info("Java版本: {}", System.getProperty("java.version"));
            startupLogger.info("活动配置: {}", System.getProperty("spring.profiles.active", "default"));
        }
        
        public void logStartupComplete() {
            long duration = System.currentTimeMillis() - startTime;
            startupLogger.info("=== Mall-Admin 应用启动完成 ===");
            startupLogger.info("启动耗时: {}ms", duration);
            startupLogger.info("应用端口: {}", System.getProperty("server.port", "8080"));
            startupLogger.info("健康检查: http://localhost:{}/actuator/health", 
                System.getProperty("server.port", "8080"));
        }
    }
}